

<!DOCTYPE html>
<html lang="zh" xmlns:v-bind="http://www.w3.org/1999/xhtml">

<head><meta name="generator" content="Hexo 3.9.0">
    <title>Go语言 gorm 自定义json类型 - suke`s Notice</title>
<meta charset="utf-8">
<meta name="X-UA-Compatible" content="IE=edge">
<meta name="author" content="suke">
<meta name="description" content="在 gorm 的 stuct 中实现自定义类型，完成，
req.body=&amp;gt;(MarshaJson json...">
<meta name="keywords" content="javascript html css php server npm nodejs">

<link rel="alternate" type="application/atom+xml" title="ATOM 1.0" href="/atom.xml">

    <meta charset="utf-8">
    <meta name="X-UA-Compatible" content="IE=edge">
    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
    <meta content="telephone=no" name="format-detection">
    <meta name="renderer" content="webkit">
    <meta name="theme-color" content="#ffffff">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" integrity="sha256-eSi1q2PG6J7g7ib17yAaWMcrr5GrtohYChqibrV7PBE=" crossorigin="anonymous">
<link rel="stylesheet" href="/css/journal.css?37865666">

<script src="/js/loadCSS.js"></script>
<script>
    loadCSS("https://fonts.googleapis.com/css?family=Lora|Montserrat|Fira+Mono|Material+Icons");
    (function (d) {
        var config = {
                kitId: 'dwg1tuc',
                scriptTimeout: 3000,
                async: true
            },
            h = d.documentElement, t = setTimeout(function () {
                h.className = h.className.replace(/\bwf-loading\b/g, "") + " wf-inactive";
            }, config.scriptTimeout), tk = d.createElement("script"), f = false,
            s = d.getElementsByTagName("script")[0], a;
        h.className += " wf-loading";
        tk.src = 'https://use.typekit.net/' + config.kitId + '.js';
        tk.async = true;
        tk.onload = tk.onreadystatechange = function () {
            a = this.readyState;
            if (f || a && a != "complete" && a != "loaded") return;
            f = true;
            clearTimeout(t);
            try {
                Typekit.load(config)
            } catch (e) {
            }
        };
        s.parentNode.insertBefore(tk, s)
    })(document);
</script>
<noscript>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lora|Montserrat|Anonymous+Pro:400|Material+Icons">
</noscript>
</head>
<body>
<div id="top"></div>
<div id="app">
<div class="single-column-drawer-container" ref="drawer" v-bind:class="{ 'single-column-drawer-container-active': isDrawerOpen }">
    <div class="drawer-content">
        <div class="drawer-menu">
            <a class="a-block drawer-menu-item false" href="https://sukeai.netlify.com">
                Home
            </a>
            

            
            
            <a class="a-block drawer-menu-item false" href="/firends/index.html">
                朋友👬
            </a>
            
            <a class="a-block drawer-menu-item false" href="/projects/index.html">
                空闲下来做的项目
            </a>
            
            <a class="a-block drawer-menu-item false" href="/about/index.html">
                关于我
            </a>
            

            
            <a class="a-block drawer-menu-item" href="/atom.xml">
                RSS
            </a>
            
        </div>
    </div>
</div>
<transition name="fade">
    <div v-bind:class="{ 'single-column-drawer-mask': mounted }" v-if="isDrawerOpen" v-on:click="toggleDrawer"></div>
</transition>
<nav ref="navBar" class="navbar sticky-top navbar-light single-column-nav-container">
    <div ref="navBackground" class="nav-background"></div>
    <div class="container container-narrow nav-content">
        <button id="nav_dropdown_btn" class="nav-dropdown-toggle" type="button" v-on:click="toggleDrawer">
            <i class="material-icons">
                menu
            </i>
        </button>
        <a ref="navTitle" class="navbar-brand" href="/">
            suke`s Notice
        </a>
    </div>
</nav>
<div class="single-column-header-container" ref="pageHead" v-bind:style="{ transform: 'translateZ(0px) translateY('+.3*scrollY+'px)', opacity: 1-navOpacity }">
    <a href="/">
        <div class="single-column-header-title">suke`s Notice</div>
        <div class="single-column-header-subtitle">hexo博客</div>
    </a>
</div>
<div ref="sideContainer" class="side-container">
    <a class="a-block nav-head false" href="/">
        <div class="nav-title">
            有猫病.
        </div>
        <div class="nav-subtitle">
             她的眼里有光,她爱的人是谁呢 
        </div>
    </a>

    <div class="nav-link-list">
        

        
        
        <a class="a-block nav-link-item false" href="/firends/index.html">
            朋友👬
        </a>
        
        <a class="a-block nav-link-item false" href="/projects/index.html">
            空闲下来做的项目
        </a>
        
        <a class="a-block nav-link-item false" href="/about/index.html">
            关于我
        </a>
        

        
        <a class="a-block no-tint nav-link-item" href="/atom.xml">
            RSS
        </a>
        
    </div>

    
    <div class="nav-footer">
        Proudly published with Hexo<br>
        
        Theme <a href="https://github.com/SumiMakito/hexo-theme-journal/" target="_blank" rel="noreferrer noopener">Journal.</a> by <a href="https://mak1t0.cc/" target="_blank" rel="noreferrer noopener">Makito</a><br>
        
        &copy; 2020 <a href="https://sukeai.netlify.com">suke`s Notice</a>
    </div>
</div>
<div ref="extraContainer" class="extra-container">
    <div class="pagination">
        <a id="globalBackToTop" class="pagination-action animated-visibility" href="#top" :class="{ invisible: scrollY == 0 }">
            <i class="material-icons pagination-action-icon">
                keyboard_arrow_up
            </i>
        </a>

        
    </div>
</div>



<div ref="streamContainer" class="stream-container">
    <div class="post-list-container post-list-container-shadow">
        <div class="post">
            <div class="post-head-wrapper-text-only" style="background-image: url('')">
                <div class="post-title">
                    Go语言 gorm 自定义json类型
                    <div class="post-meta">
                        <time datetime="2020-03-27T11:20:34.000Z" itemprop="datePublished">
                            2020-03-27 11:20
                        </time>&nbsp;
                        
    
                        
                    </div>
                </div>
            </div>
    
            <div class="post-body-wrapper">
                <div class="post-body">
                    <h1 id="在-gorm-的-stuct-中实现自定义类型，"><a href="#在-gorm-的-stuct-中实现自定义类型，" class="headerlink" title="在 gorm 的 stuct 中实现自定义类型，"></a>在 gorm 的 stuct 中实现自定义类型，</h1><h3 id="完成，"><a href="#完成，" class="headerlink" title="完成，"></a>完成，</h3><blockquote>
<p>req.body=&gt;(MarshaJson json)=&gt;stuct=&gt;(Value grom.Model)=&gt;数据库</p>
</blockquote>
<blockquote>
<p>数据库=&gt;(Scan grom.Model)=&gt;struct=&gt;(UnmarshaJson json)=&gt;json</p>
</blockquote>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// Array json传数组类型 &gt;&gt;&gt;修复：</span></span><br><span class="line"><span class="keyword">type</span> Array []<span class="keyword">string</span></span><br><span class="line"><span class="comment">//gorm中声明数据模型的时候需要 Images      util.Array `gorm:"type:MEDIUMTEXT" json:"images" `</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// UnmarshalJSON req.body []byte=&gt;对象，记得调用json.Unmarshal要新建原始类型进行绑定，不如会死循环</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(a *Array)</span> <span class="title">UnmarshalJSON</span><span class="params">(b []<span class="keyword">byte</span>)</span> <span class="title">error</span></span> &#123;</span><br><span class="line">	<span class="comment">// b = bytes.Trim(b, "\"")</span></span><br><span class="line">	<span class="comment">// fmt.Printf("%v", string(b))</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//这里一定要新建对象</span></span><br><span class="line"><span class="comment">//json.Unmarshal调用的是 stuct.UnmarshalJSON</span></span><br><span class="line"><span class="comment">//所以这里如果直接绑定 &amp;a 会出现死循环</span></span><br><span class="line">	arr := []<span class="keyword">string</span>&#123;&#125;</span><br><span class="line">	<span class="keyword">if</span> err := json.Unmarshal(b, &amp;arr); err != <span class="literal">nil</span> &#123;</span><br><span class="line">		<span class="keyword">return</span> err <span class="comment">//如果解码失败</span></span><br><span class="line">	&#125;</span><br><span class="line">	*a = Array(arr) <span class="comment">//解码成功赋值</span></span><br><span class="line">	<span class="comment">// fmt.Printf("Array UnmarshalJSON %v \n", arr)</span></span><br><span class="line">	<span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Value 存库,对象到转储数据 标准字符 int类型</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(a Array)</span> <span class="title">Value</span><span class="params">()</span> <span class="params">(driver.Value, error)</span></span> &#123;</span><br><span class="line">	<span class="comment">// fmt.Printf("value %v \n", a)</span></span><br><span class="line">	<span class="keyword">if</span> <span class="built_in">len</span>(a) == <span class="number">0</span> &#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="literal">nil</span>, <span class="literal">nil</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//fmt.Sprint(a) []string=&gt;[a,b,c] 强制转换为字符类型，类似与js中的 obj =&gt; [object,object]</span></span><br><span class="line">    <span class="comment">//strings.Trim  [a b c]=&gt;a b c</span></span><br><span class="line">    <span class="comment">//strings.ReplaceAll a b c =&gt; a,b,c</span></span><br><span class="line">	arr := strings.ReplaceAll(strings.Trim(fmt.Sprint(a), <span class="string">"[]"</span>), <span class="string">" "</span>, <span class="string">","</span>)</span><br><span class="line">	<span class="keyword">return</span> arr, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Scan 绑定，数据库到对象,这里到数据取到到都是[]uint8字节，转化为对象</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(a *Array)</span> <span class="title">Scan</span><span class="params">(v <span class="keyword">interface</span>&#123;&#125;)</span> <span class="title">error</span></span> &#123;</span><br><span class="line">	value, ok := v.([]<span class="keyword">uint8</span>) <span class="comment">//自定义的类型 从数据库取出，scan的时候 varchar(255)和double 获取到的都是 []uint8 字节，可能哪里还有问题，之前看的一个自定义时间格式化的可以获取到time.Time类型</span></span><br><span class="line">	<span class="keyword">if</span> ok &#123;</span><br><span class="line">        <span class="comment">// 转化字节到字符串 分割字符串</span></span><br><span class="line">		arr := strings.Split(<span class="keyword">string</span>(value), <span class="string">","</span>)</span><br><span class="line">		*a = Array(arr)<span class="comment">//重新赋值Arr</span></span><br><span class="line">		<span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> fmt.Errorf(<span class="string">"%v 类型错误  scan失败"</span>, reflect.TypeOf(v))</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// MarshalJSON 对象到json转换 接口展示</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(a *Array)</span> <span class="title">MarshalJSON</span><span class="params">()</span> <span class="params">([]<span class="keyword">byte</span>, error)</span></span> &#123;</span><br><span class="line">    <span class="comment">//这里在scan后边执行 直接解码，注意新建通用类型</span></span><br><span class="line">	b, err := json.Marshal([]<span class="keyword">string</span>(*a))</span><br><span class="line">	<span class="comment">// fmt.Printf("MarshalJSON %v \n", string(b))</span></span><br><span class="line">	<span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="literal">nil</span>, err</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">// 空数组默认值，空数组返回null在前端还听难受到其实</span></span><br><span class="line">	<span class="keyword">if</span> <span class="keyword">string</span>(b) == <span class="string">"null"</span> &#123;</span><br><span class="line">		b = []<span class="keyword">byte</span>(<span class="string">`[]`</span>)</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> b, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="实现效果"><a href="#实现效果" class="headerlink" title="实现效果"></a>实现效果</h2><h3 id="请求"><a href="#请求" class="headerlink" title="请求"></a>请求</h3><figure class="highlight less"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">post</span>(<span class="string">""</span>,&#123;<span class="attribute">data</span>:&#123;<span class="attribute">arr</span>:[<span class="string">"asd"</span>,<span class="string">"asd"</span>]&#125;&#125;)</span><br></pre></td></tr></table></figure>

<h4 id="存库"><a href="#存库" class="headerlink" title="存库"></a>存库</h4><figure class="highlight 1c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">"asd,asd"</span></span><br></pre></td></tr></table></figure>

<h4 id="Response"><a href="#Response" class="headerlink" title="Response"></a>Response</h4><figure class="highlight avrasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">arr:</span>[<span class="string">"asd"</span>,<span class="string">"asd"</span>]</span><br></pre></td></tr></table></figure>


                </div>
            </div>
    
            <nav class="post-pagination">
    
    <a class="newer-posts" href="/2020-04-07/Flutter开发日记-Image网络图片加载错误处理.html">
        Previous post<br>Flutter开发日记-Image网络图片加载错误处理
    </a>
    
    <span class="page-number"></span>
    
    <a class="older-posts" href="/2020-03-16/Flutter实践.html">
        Next post<br>Flutter实践
    </a>
    
</nav>

    
            


        </div>
    </div>
    <div class="single-column-footer">
    Proudly published with Hexo<br>
    
    Theme <a href="https://github.com/SumiMakito/hexo-theme-journal/" target="_blank" rel="noreferrer noopener">Journal.</a> by <a href="https://mak1t0.cc/" target="_blank" rel="noreferrer noopener">Makito</a><br>
    
    &copy; 2020 <a href="https://sukeai.netlify.com">suke`s Notice</a>
</div>
</div>

</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.4/dist/umd/popper.min.js" integrity="sha256-EGs9T1xMHdvM1geM8jPpoo8EZ1V1VRsmcJz8OByENLA=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/js/bootstrap.min.js" integrity="sha256-VsEqElsCHSGmnmHXGQzvoWjWwoznFSZc6hs7ARLRacQ=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js" integrity="sha256-FtWfRI+thWlNz2sB3SJbwKx5PgMyKIVgwHCTwa3biXc=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/smooth-scroll@14.2.1/dist/smooth-scroll.polyfills.min.js" integrity="sha256-CI4Gq5E0io1Pv0xM3qPM+NUIOhbIBvC3GiN1Y4KhXpw=" crossorigin="anonymous"></script>
<script src="/js/journal.js?11098618"></script>



</body>
</html>
